home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CreatingGames / Utilities / E / PsiloPlayer / Src / PsiloPlayer.e
Encoding:
Text File  |  1995-11-24  |  20.0 KB  |  625 lines

  1.  
  2. OPT OSVERSION=39
  3. OPT PREPROCESS
  4.  
  5. MODULE 'tools/easygui','intuition/screens','tools/exceptions',
  6.        'intuition/intuition','protracker','graphics/rastport',
  7.        'graphics/text','asl','libraries/asl','utility/tagitem',
  8.        'dos/dos','exec/memory','xpkmaster','libraries/xpk',
  9.        'libraries/gadtools','commodities','icon','amigalib/argarray',
  10.        'exec/ports','libraries/commodities','tools/ports','utility',
  11.        'med/mmd','medplayer','med/reloc','octaplayer','playsid',
  12.        'libraries/playsidbase','exec/execbase','replay/jamcracker'
  13.  
  14.  
  15. RAISE "LIB"  IF OpenLibrary()=0,
  16.       "FONT" IF OpenFont()=0,
  17.       "DRI"  IF GetScreenDrawInfo()=0,
  18.       "ASL"  IF AllocAslRequest()=0,
  19.       "SCR"  IF LockPubScreen()=0,
  20.       "PORT" IF CreateMsgPort()=0,
  21.       "cxOB" IF CreateCxObj()=0,
  22.            1 IF CxBroker()=0
  23.  
  24.  
  25. OBJECT modinfo OF plugin
  26.     window:PTR TO window
  27. PRIVATE
  28.     rawkey:LONG
  29.     visible:INT
  30.     size:LONG
  31.     name[128]:ARRAY OF CHAR
  32.     type[128]:ARRAY OF CHAR
  33.     author[128]:ARRAY OF CHAR
  34.     comment[128]:ARRAY OF CHAR
  35. ENDOBJECT
  36.  
  37.  
  38. DEF mi:PTR TO modinfo,mp=0:PTR TO mmd0,ml=0,freq=0:PTR TO filerequester,
  39.     sreq=0:PTR TO filerequester,pl=0,mfl=0,gh=0:PTR TO guihandle,
  40.     defldir[256]:STRING,defsdir[256]:STRING,sc:PTR TO screen,
  41.     brokerPort=0:PTR TO mp,broker=0,filter=0,type=0,sg,song,minsong,maxsong
  42.  
  43. ->fs "modinfo class code"
  44. PROC modinfo(name=NIL,size=0,t=0,au=0,com=0) OF modinfo
  45.     IF name THEN AstrCopy(self.name,name,128) ELSE AstrCopy(self.name,'No module loaded',128)
  46.     self.size:=size
  47.     IF t THEN AstrCopy(self.type,t,128) ELSE AstrCopy(self.type,'None',128)
  48.     IF au THEN AstrCopy(self.author,au,128) ELSE AstrCopy(self.author,'Unknown',128)
  49.     IF com THEN AstrCopy(self.comment,com,128) ELSE AstrCopy(self.comment,'None',128)
  50. ENDPROC
  51.  
  52. PROC will_resize() OF modinfo IS RESIZEX
  53.  
  54. PROC min_size(fh) OF modinfo IS fh*10,fh*5
  55.  
  56. PROC render(x,y,xs,ys,wd:PTR TO window) OF modinfo
  57.     DEF rp:PTR TO rastport,w,tw,s[32]:STRING,c,dri:PTR TO drawinfo,
  58.         font:PTR TO textfont
  59.     self.visible:=TRUE
  60.     self.window:=wd
  61.     font:=OpenFont(wd.wscreen.font)
  62.     dri:=GetScreenDrawInfo(wd.wscreen)
  63.     rp:=wd.rport
  64.     SetAPen(rp,dri.pens[BACKGROUNDPEN])
  65.     RectFill(rp,x,y,x+xs-1,y+ys-1)
  66.     SetAPen(rp,dri.pens[TEXTPEN])
  67.     SetFont(rp,font)
  68.     tw:=Max(TextLength(rp,'Comment: ',9),Max(TextLength(rp,'Author: ',8),Max(TextLength(rp,'Name: ',6),Max(TextLength(rp,'Size: ',6),TextLength(rp,'Type: ',6)))))
  69.     Move(rp,x,y+rp.font.baseline)
  70.     Text(rp,'Name:',5)
  71.     Move(rp,x,y+rp.font.baseline+rp.font.ysize)
  72.     Text(rp,'Size:',5)
  73.     Move(rp,x,y+rp.font.baseline+Shl(rp.font.ysize,1))
  74.     Text(rp,'Type:',5)
  75.     Move(rp,x,y+rp.font.baseline+Shl(rp.font.ysize,1)+rp.font.ysize)
  76.     Text(rp,'Author:',7)
  77.     Move(rp,x,y+rp.font.baseline+Shl(rp.font.ysize,2))
  78.     Text(rp,'Comment:',8)
  79.     StringF(s,'\d',self.size)
  80.     Move(rp,x+tw,y+rp.font.baseline)
  81.     c:=StrLen(self.name)
  82.     w:=TextLength(rp,self.name,c)
  83.     WHILE w>(xs-tw)
  84.         DEC c
  85.         EXIT c=0
  86.         w:=TextLength(rp,self.name,c)
  87.     ENDWHILE
  88.     IF c THEN Text(rp,self.name,c)
  89.     Move(rp,x+tw,y+rp.font.baseline+rp.font.ysize)
  90.     c:=StrLen(s)
  91.     w:=TextLength(rp,s,c)
  92.     WHILE w>(xs-tw)
  93.         DEC c
  94.         EXIT c=0
  95.         w:=TextLength(rp,s,c)
  96.     ENDWHILE
  97.     IF c THEN Text(rp,s,c)
  98.     Move(rp,x+tw,y+rp.font.baseline+Shl(rp.font.ysize,1))
  99.     c:=StrLen(self.type)
  100.     w:=TextLength(rp,self.type,c)
  101.     WHILE w>(xs-tw)
  102.         DEC c
  103.         EXIT c=0
  104.         w:=TextLength(rp,self.type,c)
  105.     ENDWHILE
  106.     IF c THEN Text(rp,self.type,c)
  107.     Move(rp,x+tw,y+rp.font.baseline+Shl(rp.font.ysize,1)+rp.font.ysize)
  108.     c:=StrLen(self.author)
  109.     w:=TextLength(rp,self.author,c)
  110.     WHILE w>(xs-tw)
  111.         DEC c
  112.         EXIT c=0
  113.         w:=TextLength(rp,self.author,c)
  114.     ENDWHILE
  115.     IF c THEN Text(rp,self.author,c)
  116.     Move(rp,x+tw,y+rp.font.baseline+Shl(rp.font.ysize,2))
  117.     c:=StrLen(self.comment)
  118.     w:=TextLength(rp,self.comment,c)
  119.     WHILE w>(xs-tw)
  120.         DEC c
  121.         EXIT c=0
  122.         w:=TextLength(rp,self.comment,c)
  123.     ENDWHILE
  124.     IF c THEN Text(rp,self.comment,c)
  125.     FreeScreenDrawInfo(wd.wscreen,dri)
  126.     CloseFont(font)
  127. ENDPROC
  128.  
  129. PROC clear_render(u) OF modinfo
  130.     self.visible:=FALSE
  131.     self.window:=NIL
  132. ENDPROC
  133.  
  134. PROC message_test(imsg:PTR TO intuimessage,wd:PTR TO window) OF modinfo
  135.     IF imsg.class=IDCMP_RAWKEY
  136.         self.rawkey:=imsg.code
  137.         RETURN TRUE
  138.     ENDIF
  139. ENDPROC FALSE
  140.  
  141. PROC message_action(wd:PTR TO window) OF modinfo
  142.     DEF k
  143.     k:=self.rawkey
  144.     SELECT k
  145.         CASE $19
  146.             play()
  147.         CASE $21
  148.             stop()
  149.         CASE $12
  150.             eject()
  151.         CASE $34
  152.             save()
  153.         CASE $28
  154.             load()
  155.         CASE $45
  156.             RETURN TRUE
  157.         CASE CURSORLEFT
  158.             prev()
  159.         CASE CURSORRIGHT
  160.             next()
  161.     ENDSELECT
  162. ENDPROC FALSE
  163.  
  164. PROC setname(name=0) OF modinfo
  165.     IF name THEN AstrCopy(self.name,name,128) ELSE AstrCopy(self.name,'No module loaded',128)
  166.     IF self.visible THEN self.render(self.x,self.y,self.xs,self.ys,self.window)
  167. ENDPROC
  168.  
  169. PROC setsize(size=0) OF modinfo
  170.     self.size:=size
  171.     IF self.visible THEN self.render(self.x,self.y,self.xs,self.ys,self.window)
  172. ENDPROC
  173.  
  174. PROC settype(t=0) OF modinfo
  175.     IF t THEN AstrCopy(self.type,t,128) ELSE AstrCopy(self.type,'None',128)
  176.     IF self.visible THEN self.render(self.x,self.y,self.xs,self.ys,self.window)
  177. ENDPROC
  178.  
  179. PROC setauthor(au=0) OF modinfo
  180.     IF au THEN AstrCopy(self.author,au,128) ELSE AstrCopy(self.author,'Unknown',128)
  181.     IF self.visible THEN self.render(self.x,self.y,self.xs,self.ys,self.window)
  182. ENDPROC
  183.  
  184. PROC setcomment(com=0) OF modinfo
  185.     IF com THEN AstrCopy(self.comment,com,128) ELSE AstrCopy(self.comment,'None',128)
  186.     IF self.visible THEN self.render(self.x,self.y,self.xs,self.ys,self.window)
  187. ENDPROC
  188.  
  189. PROC setinfo(name=0,size=0,t=0,au=0,com=0) OF modinfo
  190.     IF name THEN AstrCopy(self.name,name,128) ELSE AstrCopy(self.name,'No module loaded',128)
  191.     self.size:=size
  192.     IF t THEN AstrCopy(self.type,t,128) ELSE AstrCopy(self.type,'None',128)
  193.     IF au THEN AstrCopy(self.author,au,128) ELSE AstrCopy(self.author,'Unknown',128)
  194.     IF com THEN AstrCopy(self.comment,com,128) ELSE AstrCopy(self.comment,'None',128)
  195.     IF self.visible THEN self.render(self.x,self.y,self.xs,self.ys,self.window)
  196. ENDPROC
  197. ->fe
  198.  
  199. PROC main() HANDLE
  200.     DEF res=-1,mask=0,sig,ttypes=NIL,msg,msgtype,msgid
  201.  
  202.     aslbase:=OpenLibrary('asl.library',37)
  203.     xpkbase:=OpenLibrary('xpkmaster.library',2)
  204.     iconbase:=OpenLibrary('icon.library',37)
  205.     cxbase:=OpenLibrary('commodities.library',37)
  206.     utilitybase:=OpenLibrary('utility.library',37)
  207.  
  208.     brokerPort:=CreateMsgPort()
  209.     IF (ttypes:=argArrayInit())=0 THEN Raise("args")
  210.     broker:=CxBroker([NB_VERSION,0,
  211.                       'PsiloPlayer',
  212.                       'PsiloPlayer v1.0',
  213.                       'A small module player',
  214.                       NBU_UNIQUE OR NBU_NOTIFY,COF_SHOW_HIDE,
  215.                       argInt(ttypes,'CX_PRIORITY',0),0,
  216.                       brokerPort,0]:newbroker,NIL)
  217.     AttachCxObj(broker,filter:=CxFilter(argString(ttypes,'CX_POPKEY','ctrl alt d')))
  218.     AttachCxObj(filter,CxSender(brokerPort,23))
  219.     AttachCxObj(filter,CxTranslate(NIL))
  220.     IF CxObjError(filter) THEN Raise("cxFU")
  221.     ActivateCxObj(broker,TRUE)
  222.  
  223.     loadprefs()
  224.  
  225.     freq:=AllocAslRequest(ASL_FILEREQUEST,[ASLFR_PRIVATEIDCMP,TRUE,
  226.                                            ASLFR_SLEEPWINDOW,TRUE,
  227.                                            ASLFR_TITLETEXT,'Select a module to load',
  228.                                            ASLFR_POSITIVETEXT,'Load',
  229.                                            ASLFR_NEGATIVETEXT,'Cancel',
  230.                                            ASLFR_REJECTICONS,TRUE,
  231.                                            ASLFR_INITIALDRAWER,defldir,
  232.                                            TAG_DONE])
  233.     sreq:=AllocAslRequest(ASL_FILEREQUEST,[ASLFR_PRIVATEIDCMP,TRUE,
  234.                                            ASLFR_SLEEPWINDOW,TRUE,
  235.                                            ASLFR_TITLETEXT,'Select filename to save as',
  236.                                            ASLFR_POSITIVETEXT,'Save',
  237.                                            ASLFR_NEGATIVETEXT,'Cancel',
  238.                                            ASLFR_REJECTICONS,TRUE,
  239.                                            ASLFR_DOSAVEMODE,TRUE,
  240.                                            ASLFR_INITIALDRAWER,defsdir,
  241.                                            TAG_DONE])
  242.  
  243.     sc:=LockPubScreen(NIL)
  244.  
  245.     IF Stricmp('yes',argString(ttypes,'CX_POPUP','yes'))=0 THEN opengui()
  246.  
  247.     WHILE res<0
  248.         mask:=Shl(1,brokerPort.sigbit)
  249.         IF gh THEN mask:=Or(mask,gh.sig)
  250.         sig:=Wait(mask)
  251.         IF And(sig,Shl(1,brokerPort.sigbit))
  252.             WHILE msg:=GetMsg(brokerPort)
  253.                 msgtype:=CxMsgType(msg)
  254.                 msgid:=CxMsgID(msg)
  255.                 ReplyMsg(msg)
  256.                 SELECT msgtype
  257.                     CASE CXM_IEVENT
  258.                         IF msgid=23
  259.                             IF gh THEN closegui() ELSE opengui()
  260.                         ENDIF
  261.                     CASE CXM_COMMAND
  262.                         SELECT msgid
  263.                             CASE CXCMD_APPEAR
  264.                                 opengui()
  265.                             CASE CXCMD_DISAPPEAR
  266.                                 closegui()
  267.                             CASE CXCMD_DISABLE
  268.                                 ActivateCxObj(broker,FALSE)
  269.                             CASE CXCMD_ENABLE
  270.                                 ActivateCxObj(broker,TRUE)
  271.                             CASE CXCMD_KILL
  272.                                 res:=0
  273.                             CASE CXCMD_UNIQUE
  274.                                 opengui()
  275.                         ENDSELECT
  276.                 ENDSELECT
  277.             ENDWHILE
  278.         ELSEIF gh
  279.             IF And(sig,gh.sig) THEN res:=guimessage(gh)
  280.             IF res=23
  281.                 res:=-1
  282.                 closegui()
  283.             ENDIF
  284.         ENDIF
  285.     ENDWHILE
  286.  
  287.     saveprefs()
  288.  
  289. EXCEPT DO
  290.     eject()
  291.     closegui()
  292.     IF sc THEN UnlockPubScreen(NIL,sc)
  293.     IF sreq THEN FreeAslRequest(sreq)
  294.     IF freq THEN FreeAslRequest(freq)
  295.     IF broker THEN DeleteCxObjAll(broker)
  296.     IF ttypes THEN argArrayDone()
  297.     IF brokerPort THEN deletePortSafely(brokerPort)
  298.     IF utilitybase THEN CloseLibrary(utilitybase)
  299.     IF cxbase THEN CloseLibrary(cxbase)
  300.     IF iconbase THEN CloseLibrary(iconbase)
  301.     IF xpkbase THEN CloseLibrary(xpkbase)
  302.     IF aslbase THEN CloseLibrary(aslbase)
  303.     IF exception>1 THEN report_exception()
  304. ENDPROC
  305.  
  306. PROC opengui()
  307.     IF gh THEN RETURN
  308.     gh:=guiinit('PsiloPlayer',  [ROWS,
  309.                                     [BAR],
  310.                                     [BEVELR,[PLUGIN,0,NEW mi.modinfo(name(mp,type),ml,typename(type),author(mp,type),comment(mp,type))]],
  311.                                     [BAR],
  312.                                     sg:=[TEXT,'No module loaded',0,TRUE,10],
  313.                                     [EQCOLS,
  314.                                         [SBUTTON,{play},'Play'],
  315.                                         [SBUTTON,{stop},'Stop'],
  316.                                         [SBUTTON,{prev},'Prev'],
  317.                                         [SBUTTON,{next},'Next'],
  318.                                         [SBUTTON,{eject},'Eject'],
  319.                                         [SBUTTON,{save},'Save'],
  320.                                         [SBUTTON,{load},'Load']
  321.                                     ],
  322.                                     [BAR]
  323.                                 ],0,sc,0,[NM_TITLE,0,'Project',0,0,0,0,
  324.                                           NM_ITEM,0, 'Load module...','L',NM_COMMANDSTRING,0,{load},
  325.                                           NM_ITEM,0, 'Save module...','V',NM_COMMANDSTRING,0,{save},
  326.                                           NM_ITEM,0, NM_BARLABEL,0,0,0,0,
  327.                                           NM_ITEM,0, 'Eject module','E',NM_COMMANDSTRING,0,{eject},
  328.                                           NM_ITEM,0, NM_BARLABEL,0,0,0,0,
  329.                                           NM_ITEM,0, 'Hide','H',0,0,23,
  330.                                           NM_ITEM,0, 'Quit','ESC',NM_COMMANDSTRING,0,0,
  331.                                           NM_TITLE,0,'Edit',0,0,0,0,
  332.                                           NM_ITEM,0, 'Play','P',NM_COMMANDSTRING,0,{play},
  333.                                           NM_ITEM,0, 'Stop','S',NM_COMMANDSTRING,0,{stop},
  334.                                           NM_ITEM,0, NM_BARLABEL,0,0,0,0,
  335.                                           NM_ITEM,0, 'Previous song','LEFT',NM_COMMANDSTRING,0,{prev},
  336.                                           NM_ITEM,0, 'Next song','RIGHT',NM_COMMANDSTRING,0,{next},
  337.                                           NM_END,0,0,0,0,0,0
  338.                                          ]:newmenu)
  339. ENDPROC
  340.  
  341. PROC closegui(i=0)
  342.     IF gh
  343.         cleangui(gh)
  344.         gh:=0
  345.     ENDIF
  346. ENDPROC
  347.  
  348. PROC load(i=0)
  349.     IF AslRequest(freq,[ASLFR_WINDOW,mi.window,TAG_DONE])=0 THEN RETURN
  350.     loadmodule(freq.drawer,freq.file)
  351. ENDPROC
  352.  
  353. PROC loadmodule(d,n)
  354.     DEF s[512]:STRING
  355.     IF mp THEN eject()
  356.     StrCopy(s,d)
  357.     AddPart(s,n,512)
  358.     SetStr(s,StrLen(s))
  359.     status('Loading module...')
  360.     XpkUnpack([XPK_INNAME,s,XPK_GETOUTBUF,{mp},XPK_GETOUTLEN,{ml},
  361.                XPK_GETOUTBUFLEN,{mfl},XPK_OUTMEMTYPE,MEMF_CHIP,
  362.                XPK_PASSTHRU,TRUE,TAG_DONE])
  363.     IF (type:=checkformat(mp))=0
  364.         FreeMem(mp,mfl)
  365.         mp:=0
  366.         status('Wrong format!')
  367.     ELSE
  368.         mi.setinfo(name(mp,type),ml,typename(type),author(mp,type),comment(mp,type))
  369.         play()
  370.     ENDIF
  371. ENDPROC
  372.  
  373. PROC save(i=0)
  374.     IF mp=0
  375.         status('Load a module first!')
  376.     ELSE
  377.         IF AslRequest(sreq,[ASLFR_WINDOW,mi.window,
  378.                             ASLFR_INITIALFILE,freq.file,
  379.                             TAG_DONE])=0 THEN RETURN
  380.         status('Saving module...')
  381.         savemodule(sreq.drawer,sreq.file)
  382.         status('Module saved.')
  383.     ENDIF
  384. ENDPROC
  385.  
  386. PROC savemodule(d,n)
  387.     DEF s[512]:STRING
  388.     StrCopy(s,d)
  389.     AddPart(s,n,512)
  390.     SetStr(s,StrLen(s))
  391.     XpkPack([XPK_INBUF,mp,XPK_INLEN,ml,XPK_OUTNAME,s,
  392.              XPK_PACKMETHOD,'SQSH',XPK_PACKMODE,100,
  393.              TAG_DONE])
  394. ENDPROC
  395.  
  396. PROC play(i=0)
  397.     DEF execbase:PTR TO execbase
  398.     IF mp=0 THEN status('Load a module first!')
  399.     IF mp AND (pl=0)
  400.         BSET    #1,$BFE001
  401.         SELECT type
  402.             CASE 1  -> ProTracker
  403.                 ptbase:=OpenLibrary('protracker.library',1)
  404.                 pl:=Mt_StartInt(mp)
  405.                 IF pl=0
  406.                     CloseLibrary(ptbase)
  407.                     ptbase:=0
  408.                 ENDIF
  409.             CASE 2  -> MED
  410.                 medplayerbase:=OpenLibrary('medplayer.library',5)
  411.                 pl:=IF GetPlayer(0) THEN FALSE ELSE TRUE
  412.                 IF pl
  413.                     SetModnum(song)
  414.                     PlayModule(mp)
  415.                 ELSE
  416.                     CloseLibrary(medplayerbase)
  417.                     medplayerbase:=0
  418.                 ENDIF
  419.             CASE 3  -> OctaMED
  420.                 octaplayerbase:=OpenLibrary('octaplayer.library',5)
  421.                 pl:=IF GetPlayer8() THEN FALSE ELSE TRUE
  422.                 IF pl
  423.                     SetModnum8(song)
  424.                     PlayModule8(mp)
  425.                 ELSE
  426.                     CloseLibrary(octaplayerbase)
  427.                     octaplayerbase:=0
  428.                 ENDIF
  429.             CASE 4  -> PlaySID
  430.                 playsidbase:=OpenLibrary('playsid.library',1)
  431.                 pl:=AllocEmulResource()
  432.                 IF pl=0
  433.                     execbase:=Long(4)
  434.                     SetVertFreq(execbase.powersupplyfrequency)
  435.                     SetModule(mp,mp,ml)
  436.                     pl:=StartSong(song)
  437.                     IF pl THEN FreeEmulResource()
  438.                 ENDIF
  439.                 IF pl
  440.                     CloseLibrary(playsidbase)
  441.                     playsidbase:=0
  442.                 ENDIF
  443.                 pl:=IF pl THEN FALSE ELSE TRUE
  444.             CASE 5  -> JamCracker
  445.                 pl:=jc_StartInt(mp)
  446.         ENDSELECT
  447.         IF pl THEN status('Playing module...') ELSE status('Can''t play module!')
  448.     ENDIF
  449. ENDPROC
  450.  
  451. PROC eject(i=0)
  452.     IF mp
  453.         stop()
  454.         FreeMem(mp,mfl)
  455.         mp:=0;ml:=0
  456.         type:=0
  457.         mi.setinfo()
  458.         status('Module ejected.')
  459.     ELSE
  460.         status('No module loaded!')
  461.     ENDIF
  462. ENDPROC
  463.  
  464. PROC stop(i=0)
  465.     IF pl
  466.         SELECT type
  467.             CASE 1  -> ProTracker
  468.                 Mt_StopInt()
  469.                 CloseLibrary(ptbase)
  470.                 ptbase:=0
  471.             CASE 2  -> MED
  472.                 StopPlayer()
  473.                 FreePlayer()
  474.                 CloseLibrary(medplayerbase)
  475.                 medplayerbase:=0
  476.             CASE 3  -> OctaMED
  477.                 StopPlayer8()
  478.                 FreePlayer8()
  479.                 CloseLibrary(octaplayerbase)
  480.                 octaplayerbase:=0
  481.             CASE 4  -> PlaySID
  482.                 StopSong()
  483.                 FreeEmulResource()
  484.                 CloseLibrary(playsidbase)
  485.                 playsidbase:=0
  486.             CASE 5  -> JamCracker
  487.                 jc_StopInt()
  488.         ENDSELECT
  489.         pl:=0
  490.         status('Module stopped.')
  491.     ELSE
  492.         status('No module playing!')
  493.     ENDIF
  494. ENDPROC
  495.  
  496. PROC checkformat(m:PTR TO mmd0)
  497.     DEF v
  498.     song:=0
  499.     minsong:=0
  500.     maxsong:=0
  501.     IF Long(m+1080)="M.K." THEN RETURN 1
  502.     v:=Long(m)
  503.     IF v="BeEp" THEN RETURN 5
  504.     IF v="PSID"
  505.         song:=m::sidheader.defsong
  506.         minsong:=1
  507.         maxsong:=m::sidheader.number
  508.         RETURN 4
  509.     ENDIF
  510.     IF (v="MMD0") OR (v="MMD1") OR (v="MMD2")
  511.         relocModule(m)
  512.         song:=0
  513.         minsong:=0
  514.         maxsong:=m.extra_songs
  515.         RETURN IF And(m.song.flags,FLAG_8CHANNEL) THEN 3 ELSE 2
  516.     ENDIF
  517. ENDPROC 0
  518.  
  519. PROC name(mod:PTR TO mmd0,t)
  520.     IF mod=0 THEN RETURN 'No module loaded'
  521.     SELECT t
  522.         CASE 0  -> None loaded
  523.             RETURN 'Fnord!'
  524.         CASE 1  -> ProTracker
  525.             PutChar(mod+19,0)
  526.             RETURN mod
  527.         CASE 2  -> MED
  528.             RETURN mod.expdata.songname
  529.         CASE 3  -> OctaMED
  530.             RETURN mod.expdata.songname
  531.         CASE 4  -> PlaySID
  532.             RETURN mod::sidheader.name
  533.         CASE 5  -> JamCracker
  534.             RETURN freq.file
  535.     ENDSELECT
  536. ENDPROC 'Untitled'
  537.  
  538. PROC author(mod:PTR TO mmd0,t)
  539.     DEF i,j
  540.     IF mod=0 THEN RETURN 'No module loaded'
  541.     SELECT t
  542.         CASE 0  -> None loaded
  543.             RETURN 'Prof. Adam Weishaupt'
  544.         CASE 1  -> ProTracker
  545.             IF Char(mod+20)<>"#" THEN RETURN 'Unknown'
  546.             i:=mod+21
  547.             WHILE Char(i)="#" DO INC i
  548.             j:=i
  549.             WHILE (Char(i)<>"#") AND (i<(mod+42)) DO INC i
  550.             IF Char(i)="#" THEN PutChar(i,0) ELSE PutChar(i-1,0)
  551.             RETURN j
  552.         CASE 2  -> MED
  553.             RETURN 'Unknown'
  554.         CASE 3  -> OctaMED
  555.             RETURN 'Unknown'
  556.         CASE 4  -> PlaySID
  557.             RETURN mod::sidheader.author
  558.         CASE 5  -> JamCracker
  559.             RETURN 'Unknown'
  560.     ENDSELECT
  561. ENDPROC 'Untitled'
  562.  
  563. PROC comment(mod:PTR TO mmd0,t)
  564.     IF mod=0 THEN RETURN 'No module loaded'
  565.     SELECT t
  566.         CASE 0  -> None loaded
  567.             RETURN 'Fnord!'
  568.         CASE 1  -> ProTracker
  569.             RETURN 'None'
  570.         CASE 2  -> MED
  571.             RETURN mod.expdata.annotxt
  572.         CASE 3  -> OctaMED
  573.             RETURN mod.expdata.annotxt
  574.         CASE 4  -> PlaySID
  575.             RETURN mod::sidheader.copyright
  576.         CASE 5  -> JamCracker
  577.             RETURN 'None'
  578.     ENDSELECT
  579. ENDPROC 'Untitled'
  580.  
  581. PROC typename(t) IS ListItem(['None','ProTracker','OctaMED 4-Channel',
  582.                               'OctaMED 8-Channel','PlaySID','JamCracker'],t)
  583.  
  584. PROC status(t) IS settext(gh,sg,t)
  585.  
  586. PROC loadprefs()
  587.     DEF fh
  588.     fh:=Open('ENVARC:PsiloPlayer.prefs',MODE_OLDFILE)
  589.     IF fh
  590.         ReadStr(fh,defldir)
  591.         ReadStr(fh,defsdir)
  592.         Close(fh)
  593.     ENDIF
  594. ENDPROC
  595.  
  596. PROC saveprefs()
  597.     DEF fh
  598.     fh:=Open('ENVARC:PsiloPlayer.prefs',MODE_NEWFILE)
  599.     IF fh=0 THEN Raise("FILE")
  600.     VfPrintf(fh,'%s\n%s\n',[freq.drawer,sreq.drawer])
  601.     Close(fh)
  602. ENDPROC
  603.  
  604. PROC next(i=0)
  605.     IF song<maxsong
  606.         stop()
  607.         INC song
  608.         play()
  609.     ELSE
  610.         status('This is the last song!')
  611.     ENDIF
  612. ENDPROC
  613.  
  614. PROC prev(i=0)
  615.     IF song>minsong
  616.         stop()
  617.         DEC song
  618.         play()
  619.     ELSE
  620.         status('This is the first song!')
  621.     ENDIF
  622. ENDPROC
  623.  
  624.  
  625.